﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace SplendidCRM.TopicCategories
{
    public partial class EditView : SplendidControl
    {
        protected _controls.ModuleHeader ctlModuleHeader;
        protected _controls.DynamicButtons ctlDynamicButtons;
        // 01/13/2010 Paul.  Add footer buttons. 
        protected _controls.DynamicButtons ctlFooterButtons;

        protected Guid gID;
        protected HtmlTable tblMain;

        // 11/06/2010 Paul.  Move LoadFile() to Crm.NoteAttachments. 

        protected void Page_Command(Object sender, CommandEventArgs e)
        {
            // 08/21/2005 Paul.  Redirect to parent if that is where the note was originated. 
            Guid gPARENT_ID = Sql.ToGuid(Request["PARENT_ID"]);
            string sMODULE = String.Empty;
            string sPARENT_TYPE = String.Empty;
            string sPARENT_NAME = String.Empty;
            try
            {
                SqlProcs.spPARENT_Get(ref gPARENT_ID, ref sMODULE, ref sPARENT_TYPE, ref sPARENT_NAME);
            }
            catch (Exception ex)
            {
                SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
                // The only possible error is a connection failure, so just ignore all errors. 
                gPARENT_ID = Guid.Empty;
            }
            if (e.CommandName == "Save")
            {
                try
                {
                    // 01/16/2006 Paul.  Enable validator before validating page. 
                    this.ValidateEditViewFields(m_sMODULE + "." + LayoutEditView);
                    // 11/10/2010 Paul.  Apply Business Rules. 
                    this.ApplyEditViewValidationEventRules(m_sMODULE + "." + LayoutEditView);
                    if (Page.IsValid)
                    {
                        // 09/09/2009 Paul.  Use the new function to get the table name. 
                        string sTABLE_NAME = Crm.Modules.TableName(m_sMODULE);
                        DataTable dtCustomFields = SplendidCache.FieldsMetaData_Validated(sTABLE_NAME);
                        DbProviderFactory dbf = DbProviderFactories.GetFactory();
                        using (IDbConnection con = dbf.CreateConnection())
                        {
                            con.Open();
                            // 11/18/2007 Paul.  Use the current values for any that are not defined in the edit view. 
                            DataRow rowCurrent = null;
                            DataTable dtCurrent = new DataTable();
                            if (!Sql.IsEmptyGuid(gID))
                            {
                                string sSQL;
                                sSQL = "select *           " + ControlChars.CrLf
                                     + "  from vwTOPICS_Edit" + ControlChars.CrLf;
                                using (IDbCommand cmd = con.CreateCommand())
                                {
                                    cmd.CommandText = sSQL;
                                    Security.Filter(cmd, m_sMODULE, "edit");
                                    Sql.AppendParameter(cmd, gID, "ID", false);
                                    using (DbDataAdapter da = dbf.CreateDataAdapter())
                                    {
                                        ((IDbDataAdapter)da).SelectCommand = cmd;
                                        da.Fill(dtCurrent);
                                        if (dtCurrent.Rows.Count > 0)
                                        {
                                            rowCurrent = dtCurrent.Rows[0];
                                            // 12/09/2008 Paul.  Throw an exception if the record has been edited since the last load. 
                                            DateTime dtLAST_DATE_MODIFIED = Sql.ToDateTime(ViewState["LAST_DATE_MODIFIED"]);
                                            if (Sql.ToBoolean(Application["CONFIG.enable_concurrency_check"]) && dtLAST_DATE_MODIFIED != DateTime.MinValue && Sql.ToDateTime(rowCurrent["DATE_MODIFIED"]) > dtLAST_DATE_MODIFIED)
                                                throw (new Exception(String.Format(L10n.Term(".ERR_CONCURRENCY_EXCEPTION"), dtLAST_DATE_MODIFIED)));
                                        }
                                        else
                                        {
                                            // 11/19/2007 Paul.  If the record is not found, clear the ID so that the record cannot be updated.
                                            // It is possible that the record exists, but that ACL rules prevent it from being selected. 
                                            gID = Guid.Empty;
                                        }
                                    }
                                }
                            }

                            // 11/10/2010 Paul.  Apply Business Rules. 
                            this.ApplyEditViewPreSaveEventRules(m_sMODULE + "." + LayoutEditView, rowCurrent);

                            // 10/07/2009 Paul.  We need to create our own global transaction ID to support auditing and workflow on SQL Azure, PostgreSQL, Oracle, DB2 and MySQL. 
                            using (IDbTransaction trn = Sql.BeginTransaction(con))
                            {
                                try
                                {
                                    // 11/18/2007 Paul.  Use the current values for any that are not defined in the edit view. 
                                    // 12/29/2007 Paul.  TEAM_ID is now in the stored procedure. 
                                    SqlProcs.spTOPICS_Update
                                        (ref gID
                                        , new DynamicControl(this, rowCurrent, "NAME").Text
                                        , new DynamicControl(this, rowCurrent, "DESCRIPTION").Text
                                        , new DynamicControl(this, rowCurrent, "PARENT_ID").Text
                                        , trn
                                        );
                                    
                                    SplendidDynamic.UpdateCustomFields(this, trn, gID, sTABLE_NAME, dtCustomFields);
                                    // 08/26/2010 Paul.  Add new record to tracker. 
                                    SqlProcs.spTRACKER_Update
                                        (Security.USER_ID
                                        , m_sMODULE
                                        , gID
                                        , new DynamicControl(this, rowCurrent, "NAME").Text
                                        , trn
                                        );
                                    trn.Commit();
                                }
                                catch (Exception ex)
                                {
                                    trn.Rollback();
                                    SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
                                    ctlDynamicButtons.ErrorText = ex.Message;
                                    return;
                                }
                            }
                        }
                        // 11/10/2010 Paul.  Apply Business Rules. 
                        this.ApplyEditViewPostSaveEventRules(m_sMODULE + "." + LayoutEditView);

                        if (!Sql.IsEmptyString(RulesRedirectURL))
                            Response.Redirect(RulesRedirectURL);
                        else if (!Sql.IsEmptyGuid(gPARENT_ID))
                            Response.Redirect("~/" + sMODULE + "/edit.aspx?ID=" + gPARENT_ID.ToString());
                        else
                            Response.Redirect("edit.aspx?ID=" + gID.ToString());
                    }
                }
                catch (Exception ex)
                {
                    SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
                    ctlDynamicButtons.ErrorText = ex.Message;
                }
            }
            else if (e.CommandName == "Cancel")
            {
                if (!Sql.IsEmptyGuid(gPARENT_ID))
                    Response.Redirect("~/" + sMODULE + "/edit.aspx?ID=" + gPARENT_ID.ToString());
                else if (Sql.IsEmptyGuid(gID))
                    Response.Redirect("default.aspx");
                else
                    Response.Redirect("edit.aspx?ID=" + gID.ToString());
            }
        }

        private void Page_Load(object sender, System.EventArgs e)
        {
            SetPageTitle(L10n.Term(".moduleList." + m_sMODULE));
            // 06/04/2006 Paul.  Visibility is already controlled by the ASPX page, but it is probably a good idea to skip the load. 
            this.Visible = (SplendidCRM.Security.GetUserAccess(m_sMODULE, "edit") >= 0);
            if (!this.Visible)
                return;

            try
            {
                gID = Sql.ToGuid(Request["ID"]);
                if (!IsPostBack)
                {
                    // 07/29/2005 Paul.  SugarCRM 3.0 does not allow the NONE option. 
                    //lstPARENT_TYPE     .Items.Insert(0, new ListItem(L10n.Term(".LBL_NONE"), ""));
                    Guid gDuplicateID = Sql.ToGuid(Request["DuplicateID"]);
                    if (!Sql.IsEmptyGuid(gID) || !Sql.IsEmptyGuid(gDuplicateID))
                    {
                        DbProviderFactory dbf = DbProviderFactories.GetFactory();
                        using (IDbConnection con = dbf.CreateConnection())
                        {
                            string sSQL;
                            sSQL = "select *           " + ControlChars.CrLf
                                 + "  from vwTOPIC_CATEGORIES_EDIT" + ControlChars.CrLf;
                            using (IDbCommand cmd = con.CreateCommand())
                            {
                                cmd.CommandText = sSQL;
                                // 11/24/2006 Paul.  Use new Security.Filter() function to apply Team and ACL security rules.
                                Security.Filter(cmd, m_sMODULE, "edit");
                                if (!Sql.IsEmptyGuid(gDuplicateID))
                                {
                                    Sql.AppendParameter(cmd, gDuplicateID, "ID", false);
                                    gID = Guid.Empty;
                                }
                                else
                                {
                                    Sql.AppendParameter(cmd, gID, "ID", false);
                                }
                                con.Open();

                                if (bDebug)
                                    RegisterClientScriptBlock("SQLCode", Sql.ClientScriptBlock(cmd));

                                // 11/22/2010 Paul.  Convert data reader to data table for Rules Wizard. 
                                using (DbDataAdapter da = dbf.CreateDataAdapter())
                                {
                                    ((IDbDataAdapter)da).SelectCommand = cmd;
                                    using (DataTable dtCurrent = new DataTable())
                                    {
                                        da.Fill(dtCurrent);
                                        if (dtCurrent.Rows.Count > 0)
                                        {
                                            DataRow rdr = dtCurrent.Rows[0];
                                            // 11/11/2010 Paul.  Apply Business Rules. 
                                            this.ApplyEditViewPreLoadEventRules(m_sMODULE + "." + LayoutEditView, rdr);

                                            ctlModuleHeader.Title = Sql.ToString(rdr["NAME"]);
                                            SetPageTitle(L10n.Term(".moduleList." + m_sMODULE) + " - " + ctlModuleHeader.Title);
                                            Utils.UpdateTracker(Page, m_sMODULE, gID, ctlModuleHeader.Title);
                                            ViewState["ctlModuleHeader.Title"] = ctlModuleHeader.Title;

                                            this.AppendEditViewFields(m_sMODULE + "." + LayoutEditView, tblMain, rdr);

                                            ctlDynamicButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, rdr);
                                            ctlFooterButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, rdr);

                                            // 12/09/2008 Paul.  Throw an exception if the record has been edited since the last load. 
                                            ViewState["LAST_DATE_MODIFIED"] = Sql.ToDateTime(rdr["DATE_MODIFIED"]);
                                            // 02/18/2009 Paul.  On load, the focus should be set to the NAME field. 
                                            TextBox txtNAME = this.FindControl("NAME") as TextBox;
                                            if (txtNAME != null)
                                                txtNAME.Focus();
                                            // 11/10/2010 Paul.  Apply Business Rules. 
                                            this.ApplyEditViewPostLoadEventRules(m_sMODULE + "." + LayoutEditView, rdr);
                                        }
                                        else
                                        {
                                            // 11/25/2006 Paul.  If item is not visible, then don't allow save 
                                            // 03/20/2008 Paul.  Dynamic buttons need to be recreated in order for events to fire. 
                                            ctlDynamicButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
                                            ctlFooterButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
                                            ctlDynamicButtons.DisableAll();
                                            ctlFooterButtons.DisableAll();
                                            ctlDynamicButtons.ErrorText = L10n.Term("ACL.LBL_NO_ACCESS");
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        this.AppendEditViewFields(m_sMODULE + "." + LayoutEditView, tblMain, null);
                        // 08/22/2010 Paul.  Automatically populate the name based on the file name. 
                        // 12/01/2010 Paul.  New naming convention for file upload fields. 
                        HtmlInputFile file = FindControl("ATTACHMENT_File") as HtmlInputFile;
                        if (file != null)
                            file.Attributes.Add("onchange", "FileNameChanged(this);");
                        // 03/20/2008 Paul.  Dynamic buttons need to be recreated in order for events to fire. 
                        ctlDynamicButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
                        ctlFooterButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
                        // 02/18/2009 Paul.  On load, the focus should be set to the NAME field. 
                        TextBox txtNAME = this.FindControl("NAME") as TextBox;
                        if (txtNAME != null)
                            txtNAME.Focus();

                        Guid gPARENT_ID = Sql.ToGuid(Request["PARENT_ID"]);
                        string sMODULE = String.Empty;
                        string sPARENT_TYPE = String.Empty;
                        string sPARENT_NAME = String.Empty;
                        SqlProcs.spPARENT_Get(ref gPARENT_ID, ref sMODULE, ref sPARENT_TYPE, ref sPARENT_NAME);
                        if (!Sql.IsEmptyGuid(gPARENT_ID))
                        {
                            new DynamicControl(this, "PARENT_ID").ID = gPARENT_ID;
                            new DynamicControl(this, "PARENT_NAME").Text = sPARENT_NAME;
                            // 02/04/2011 Paul.  We gave the PARENT_TYPE a unique name, but we need to update all EditViews and NewRecords. 
                            new DynamicControl(this, "PARENT_ID_PARENT_TYPE").SelectedValue = sPARENT_TYPE;
                        }
                        // 11/10/2010 Paul.  Apply Business Rules. 
                        this.ApplyEditViewNewEventRules(m_sMODULE + "." + LayoutEditView);
                    }
                }
                else
                {
                    // 12/02/2005 Paul.  When validation fails, the header title does not retain its value.  Update manually. 
                    ctlModuleHeader.Title = Sql.ToString(ViewState["ctlModuleHeader.Title"]);
                    SetPageTitle(L10n.Term(".moduleList." + m_sMODULE) + " - " + ctlModuleHeader.Title);
                }
            }
            catch (Exception ex)
            {
                SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
                ctlDynamicButtons.ErrorText = ex.Message;
            }
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        ///		Required method for Designer support - do not modify
        ///		the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.Load += new System.EventHandler(this.Page_Load);
            ctlDynamicButtons.Command += new CommandEventHandler(Page_Command);
            ctlFooterButtons.Command += new CommandEventHandler(Page_Command);
            m_sMODULE = "TopicCategories";
            // 02/13/2007 Paul.  Notes should highlight the Activities menu. 
            // 03/15/2011 Paul.  Change menu to use main module. 
            SetMenu(m_sMODULE);
            if (IsPostBack)
            {
                // 12/02/2005 Paul.  Need to add the edit fields in order for events to fire. 
                this.AppendEditViewFields(m_sMODULE + "." + LayoutEditView, tblMain, null);
                // 08/22/2010 Paul.  Automatically populate the name based on the file name. 
                // 12/01/2010 Paul.  New naming convention for file upload fields. 
                HtmlInputFile file = FindControl("ATTACHMENT_File") as HtmlInputFile;
                if (file != null)
                    file.Attributes.Add("onchange", "FileNameChanged(this);");
                // 03/20/2008 Paul.  Dynamic buttons need to be recreated in order for events to fire. 
                ctlDynamicButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
                ctlFooterButtons.AppendButtons(m_sMODULE + "." + LayoutEditView, Guid.Empty, null);
                // 11/10/2010 Paul.  Make sure to add the RulesValidator early in the pipeline. 
                Page.Validators.Add(new RulesValidator(this));
            }
        }
        #endregion
    }
}